/**
 * fshows.com
 * Copyright (C) 2013-2019 All Rights Reserved.
 */
package com.example.fardemo.jmh.counter;

import com.example.fardemo.jmh.counter.impl.AtomicLongCounter;
import com.example.fardemo.jmh.counter.impl.DisruptorCounter;
import com.example.fardemo.jmh.counter.impl.LongAdderCounter;
import com.example.fardemo.jmh.counter.impl.MyoneCounter;
import com.example.fardemo.jmh.counter.impl.SyncCounter;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Group;
import org.openjdk.jmh.annotations.GroupThreads;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.TearDown;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

import java.util.concurrent.TimeUnit;

/**
 * 计数器测试类
 *
 * @author Liluqing
 * @version ICounterBenchmark.java, v 0.1 2019-05-06 15:09
 */
@State(Scope.Group)
@BenchmarkMode(Mode.Throughput)
@OutputTimeUnit(TimeUnit.SECONDS)
public class ICounterBenchmark {
    @Param({"sync", "atomic","longAdder","SignCounter","DisruptorCounter"})
    private String mode;

    private ICounter counter;

    @Setup
    public void syncInit() {
        if ("sync".equals(mode)) {
            counter = new SyncCounter();
        } else if ("atomic".equals(mode)) {
            counter = new AtomicLongCounter();
        } else if ("longAdder".equals(mode)) {
            counter = new LongAdderCounter();
        } else if ("SignCounter".equals(mode)) {
            counter = new MyoneCounter();
        } else if ("DisruptorCounter".equals(mode)) {
            counter = new DisruptorCounter();
        }
    }

    @Benchmark
    @Group("counter")
    @GroupThreads(3)
    public void hit() {
        counter.hit();
    }

    @Benchmark
    @Group("counter")
    @GroupThreads(1)
    public long get() {
        return counter.getRequestSum();
    }

    @TearDown
    public void end() {
        counter.close();
    }

    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                // 导入要测试的类
                .include(ICounterBenchmark.class.getSimpleName())
                // 预热2轮
                .warmupIterations(1)
                // 度量2轮
                .measurementIterations(1)
                .forks(1)
                .build();
        new Runner(opt).run();
    }
}